package com.cabal.auth.controller;

import com.cabal.auth.dto.*;
import com.cabal.auth.facade.CabalUpdateClientFacade;
import com.cabal.auth.service.ICabalAuthService;
import com.cabal.auth.service.ICabalCommonService;
import com.cabal.common.errcode.ErrorCodeEnum;
import com.cabal.common.util.*;
import com.cabal.killed.service.KilledService;
import com.cabal.mall.service.CabalMallService;
import com.cabal.module.security.DirectReturnResult;
import com.cabal.module.security.SecurityValidMd5SignCheck;
import com.cabal.notice.service.CabalNoticeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class CabalUpdateClientController implements CabalUpdateClientFacade {

    @Value("${md5.secret_key}")
    private String secretKey;

    @Value("${mapIds:88;127}")
    private String mapIds;

    @Resource
    private CabalNoticeService cabalNoticeService;

    @Resource
    private KilledService killedService;

    @Autowired
    private ICabalAuthService cabalAuthService;

    @Resource
    private ICabalCommonService commonService;

    @Resource
    private CabalMallService cabalMallService;

    @Value("${externalCheats:SpeedGame;Speed;齿轮;变速}")
    private String externalCheats;

    @Value("${whiteList:QQPCRealTimeSpeedup}")
    private String whiteList;

    private static  Map<String, String> externalCheatsMap = new HashMap<>();

    @Override
    @SecurityValidMd5SignCheck
    public void downloadUpdateFile(@RequestBody CabalAuthDTO cabalAuthDTO, HttpServletResponse httpServletResponse) {
        try {
            cabalAuthService.downloadUpdateFile(cabalAuthDTO, httpServletResponse);
        } catch (Exception e) {
            throw new TmsServiceException(ErrorCodeEnum.PARAM_ERROR,"加签失败");
        }
    }

    @SecurityValidMd5SignCheck
    @Override
    public String getLatestVersion(@RequestParam("sign") String sign, @RequestParam("timestamp") String timestamp) {
        return cabalAuthService.getLatestVersion();
    }

    @SecurityValidMd5SignCheck
    @Override
    public String getUpdateFileSize(@RequestParam("sign") String sign, @RequestParam("timestamp") String timestamp) {
        File file = new File(System.getProperty("user.dir").concat("/template/update.zip"));
        long fileSize = FileUtils.sizeOf(file);
        return String.valueOf(fileSize);
    }

    @SecurityValidMd5SignCheck
    @Override
    public String receiveClientInfo(@RequestBody CabalClientInfoDTO cabalClientInfoDTO, HttpServletRequest request) {
        try {
            // 验签通过，下载文件
            String ip = HttpClientUtil.getClientIp(request);
            log.info("{}客户端心跳检测...", ip);
            cabalClientInfoDTO.setClientIp(ip);
            cabalAuthService.receiveClientInfo(cabalClientInfoDTO);
        } catch (Exception e) {
            throw new TmsServiceException(ErrorCodeEnum.PARAM_ERROR, "心跳接收客户端请求信息" + e);
        }
        return "SUCCESS";
    }

    @SecurityValidMd5SignCheck
    @Override
    public String updateAccountPassword(UpdateAccountPasswordDTO updateAccountPasswordDTO, HttpServletRequest request) {
        String result;
        try {
            String ip = HttpClientUtil.getClientIp(request);
            log.info("客户端请求IP地址，客户端clientId>>>>{}", ip, updateAccountPasswordDTO.getClientId());

            result = cabalAuthService.updateAccountPassword(updateAccountPasswordDTO, ip);
        } catch (Exception e) {
            throw new TmsServiceException(ErrorCodeEnum.PARAM_ERROR, "Hook更新帐号密码执行出错" + e);
        }
        return result;
    }

    @Override
    @SecurityValidMd5SignCheck
    public Map<String, String> getFileMd5Value(@RequestParam("sign") String sign, @RequestParam("clientVersion") String clientVersion, @RequestParam("timestamp") String timestamp, HttpServletRequest request) {
        String ip = HttpClientUtil.getClientIp(request);
        if(!"2.0.1".equals(clientVersion)) {
            return new HashMap<>();
        }
        log.info("{}检查文件MD5,客户端登录器版本号{}", ip, clientVersion);
        return cabalAuthService.getFileMd5Value();
    }

    @Override
    @SecurityValidMd5SignCheck
    public String updateLoginState(@RequestBody CabalClientInfoDTO cabalClientInfoDTO, HttpServletRequest request) {
        try {
            // 验签通过，下载文件
            String ip = HttpClientUtil.getClientIp(request);
            log.info("{}更新帐号登录状态...", ip);
            cabalClientInfoDTO.setClientIp(ip);
            cabalAuthService.updateLoginState(cabalClientInfoDTO);
        } catch (Exception e) {
            throw new TmsServiceException(ErrorCodeEnum.PARAM_ERROR, "更新帐号登录状态出错" + e);
        }
        return "SUCCESS";
    }

    @SecurityValidMd5SignCheck
    @Override
    public String getMapIds(@RequestParam("sign") String sign, @RequestParam("timestamp") String timestamp) {
        return mapIds;
    }

    @SecurityValidMd5SignCheck
    @Override
    public String sendKilledMessage(@RequestBody SendKilledMessageDTO sendKilledMessageDTO, HttpServletRequest request) {
        return killedService.sendKilledMessage(sendKilledMessageDTO);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String sendDungeonRecord(@RequestBody SendDungeonRecordDTO sendDungeonRecordDTO, HttpServletRequest request) {
        String ip = HttpClientUtil.getClientIp(request);
        log.info("记录副本记录，客户端请求IP地址>>>>{}", ip);
        return commonService.sendDungeonRecord(sendDungeonRecordDTO, ip);
    }

    @Override
    @SecurityValidMd5SignCheck
    public Map<String, String> getExternalCheats(String sign, String timestamp, HttpServletRequest request) {
        String[] externalCheatsArray = externalCheats.split(";");
        for(String externalCheat : externalCheatsArray) {
            externalCheatsMap.put(externalCheat, externalCheat);
        }
        return externalCheatsMap;
    }

    @Override
    @SecurityValidMd5SignCheck
    public String banAccount(@RequestParam("sign") String sign, @RequestParam("account") String account, @RequestParam("timestamp") String timestamp, @RequestParam("externalCheatsProcessName") String externalCheatsProcessName) {
        boolean isWhite = false;
        String[] whiteListArray = whiteList.split(";");
        for(String whiteList : whiteListArray) {
            if(externalCheatsProcessName.equals(whiteList)) {
                isWhite = true;
                break;
            }
        }

        if(isWhite) {
            return "FAIL";
        }

        return cabalAuthService.banAccount(account, externalCheatsProcessName);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String rechargeGmBuff(@RequestBody CabalCharacterGmBuffDTO cabalCharacterGmBuffDTO) {
        return cabalMallService.rechargeGmBuff(cabalCharacterGmBuffDTO);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String updateShopState(@RequestBody UpdateShopStateDTO updateShopStateDTO, HttpServletRequest request) {
        return cabalMallService.updateShopState(updateShopStateDTO);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String checkGmBuff(@RequestParam("account") String account) {
        return cabalMallService.checkGmBuff(account);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String pickUpItemNotice(@RequestBody PickUpItemNoticeDTO pickUpItemNoticeDTO) {
        return cabalNoticeService.pickUpItemNotice(pickUpItemNoticeDTO);
    }

    @Override
    @SecurityValidMd5SignCheck
    public CraftItemNoticeResponseDTO craftItemNotice(@RequestBody CraftItemDTO craftItemDTO) {
        return cabalNoticeService.craftItemNotice(craftItemDTO);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String getWarpIdByDungeonTargetId(@RequestParam("dungeonTargetPreId") String dungeonTargetPreId,
                                             @RequestParam("dungeonTargetBackId") String dungeonTargetBackId) {
        return cabalMallService.getWarpIdByDungeonTargetId(dungeonTargetPreId, dungeonTargetBackId);
    }

    @Override
    @SecurityValidMd5SignCheck
    @DirectReturnResult
    public String deductMallCoinHandle(@RequestParam("account") String account, @RequestParam("deductType") String deductType) {
        return cabalMallService.deductMallCoinHandle(account, deductType);
    }

    @Override
    @SecurityValidMd5SignCheck
    @DirectReturnResult
    public String getPrizeDrawCount(@RequestParam("account") String account) {
        return cabalMallService.getPrizeDrawCount(account);
    }

    @Override
    @SecurityValidMd5SignCheck
    @DirectReturnResult
    public String deductPrizeDrawCount(@RequestParam("account") String account) {
        return cabalMallService.deductPrizeDrawCount(account);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String recordPrizeDrawLog(@RequestParam("account") String account, @RequestParam("rewardLevel") String rewardLevel) {
        return cabalMallService.recordPrizeDrawLog(account, rewardLevel);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String getVipSpecialEffectsStatus(@RequestParam("characterIdValue") String characterIdValue) {
        return cabalAuthService.getVipSpecialEffectsStatus(characterIdValue);
    }

    @Override
    @SecurityValidMd5SignCheck
    public String updateVipSpecialEffectsStatus(@RequestParam("characterIdValue") String characterIdValue) {
        return cabalAuthService.updateVipSpecialEffectsStatus(characterIdValue);
    }

}
